#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <algorithm>

#define FOR(i,a,n) for(int i=a;i<n;++i)
#define REP(i,n) FOR(i,0,n)
#define v2 first
#define id second

using namespace std;

typedef pair<int,int> pii;

struct st
{
    int v2,id,maxEdgeID;
    st(int a,int b,int c)
    {
        v2=a,id=b,maxEdgeID=c;
    }
};

int ans[10010];
vector<st> query[40400];

class Graph
{
    struct Edge
    {
        int vs,vt,id;
        int addX,addY;
        Edge* next;
        void set(int a,int b,int c,int d,int e,Edge* nt = NULL)
        {
            vs=a,vt=b,addX=c,addY=d,next=nt,id=e;
        }
    };
#define EACH(i,vs) for(Edge* i=head[vs];i;i=i->next)
  public:
  int vn,arcn;
  Edge *edge,**head;
  Graph(int n,int m)
  {
    vn=n+1,arcn=0;
    edge = new Edge[m+10];
    head = new Edge*[n+10];
    fill(head,head+n+10,(Edge*)NULL);
  }
  ~Graph()
  {
    delete(edge);
    delete(head);
  }
  void AddArc(int vs,int vt,int x,int y,int id)
  {
    edge[arcn].set(vs,vt,x,y,id,head[vs]);
    head[vs]=&edge[arcn++];
  }
  pii position[40400];
  int done[40400];
  int maxEdge[40400];
  int GetDist(int v1,int v2,int eid)
  {
      printf("getdist(v1=%d,v2=%d,eid=%d) me1=%d,me2=%d\n",);
    if(done[v1]==done[v2]&&max(maxEdge[v1],maxEdge[v2])<=eid)
    {
        return abs(position[v1].first-position[v2].first)+
                abs(position[v1].second-position[v2].second);
    }
    return -1;
  }
  void dfs(int vs,int gp)
  {
    done[vs] = gp;
    REP(i,query[vs].size())
    {
        int v2 = query[vs][i].v2;
        int id = query[vs][i].id;
        int eid = query[vs][i].maxEdgeID;
        ans[id]=GetDist(vs,v2,eid);
    }
    EACH(ep,vs) if(done[ep->vt]==-1)
    {
        position[ep->vt].first = position[vs].first+ep->addX;
        position[ep->vt].second = position[vs].second+ep->addY;
        maxEdge[ep->vt] = max(maxEdge[vs],ep->id);
        dfs(ep->vt,gp);
    }
  }
  void GetAns(int k)
  {
    REP(i,vn+1) done[i]=-1,maxEdge[i]=-1;
    REP(i,vn+1) if(done[i]==-1)
    {
        position[i]=pii(0,0);
        maxEdge[i]=0;
        dfs(i,i);
    }
    REP(i,k) printf("%d\n",ans[i]);
  }
};
int main()
{
    int n,m;
    cin>>n>>m;
    Graph g(n,m*2);
    REP(i,m)
    {
        int v1,v2,w;
        char dir[2];
        scanf("%d%d%d%s",&v1,&v2,&w,dir);
        switch(dir[0])
        {
            case 'E':
                swap(v1,v2);
            case 'W':
                g.AddArc(v1,v2,-w,0,i+1);
                g.AddArc(v2,v1,w,0,i+1);
                break;
            case 'S':
                swap(v1,v2);
            case 'N':
                g.AddArc(v1,v2,0,-w,i+1);
                g.AddArc(v2,v1,0,w,i+1);
                break;
        }
    }
    int k;
    cin>>k;
    REP(i,k)
    {
        int v1,v2,eid;
        scanf("%d%d%d",&v1,&v2,&eid);
        query[v1].push_back(st(v2,i,eid));
        query[v2].push_back(st(v1,i,eid));
    }
    g.GetAns(k);
	return 0;
}
